﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Casamiel.Common;
using Casamiel.Domain;
using Casamiel.Domain.Entity;

using Casamiel.Infrastructure.Repositories;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Smooth.IoC.UnitOfWork.Interfaces;

namespace Casamiel.Application.Services
{
	public sealed class StoreService : IStoreService, INoticeService, IOrderService, IProductService
	{
		private readonly IMbrStoreRepository _mbrStoreRepository;
		private readonly IProductTagbaseRepository _productTagbaseRepository;
		private readonly IOrderBaseRepository _orderBase;
		private readonly IOrderGoodsRepository _orderGoods;
		private readonly IOrderTakeRepository _orderTake;
		private readonly IOrderDiscountCouponRepository _orderDiscount;
		private readonly INoticeBaseRepository _noticeBase;
		private readonly IMbrExtendInfoRepository _mbrExtendInfoRepository;
		private readonly IGoodBaseRepository _goodBaseRepository;
		private readonly IOrderOperationLogRepository _orderOperationLogRepository;
		public StoreService(IMbrStoreRepository mbrStoreRepository, IProductTagbaseRepository productTagbaseRepositor, IOrderBaseRepository orderBase, IOrderTakeRepository orderTake,
							IOrderDiscountCouponRepository orderDiscount, IOrderOperationLogRepository orderOperationLogRepository,
							IOrderGoodsRepository orderGoodsRepository,
							INoticeBaseRepository noticeBaseRepository, IMbrExtendInfoRepository mbrExtendInfoRepository,
							IGoodBaseRepository goodBaseRepository)
		{
			_mbrStoreRepository = mbrStoreRepository;
			_productTagbaseRepository = productTagbaseRepositor;
			_orderBase = orderBase;
			//this._orderGoods = orderGoods;
			_orderTake = orderTake;
			_orderDiscount = orderDiscount;
			_noticeBase = noticeBaseRepository;
			_goodBaseRepository = goodBaseRepository;
			_mbrExtendInfoRepository = mbrExtendInfoRepository;
			_orderOperationLogRepository = orderOperationLogRepository;
			_orderGoods = orderGoodsRepository;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="TSession"></typeparam>
		/// <param name="OrderBaseId"></param>
		/// <returns></returns>
		public async Task<Order_DiscountCouponEntity> GetByOrderBaseId<TSession>(int OrderBaseId) where TSession : class, ISession
		{
			return await _orderDiscount.GetByOrderBaseIdAsync<ICasaMielSession>(OrderBaseId).ConfigureAwait(false);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="TSession"></typeparam>
		/// <param name="entity"></param>
		/// <returns></returns>
		public async Task OrderOperationLogAddAsync<TSession>(OrderOperationLog entity) where TSession : class, ISession
		{
			await _orderOperationLogRepository.SaveAsync<TSession>(entity).ConfigureAwait(false);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="TSession"></typeparam>
		/// <param name="OrderBaseId"></param>
		/// <returns></returns>
		public async Task<List<Order_DiscountCouponEntity>> GetListByOrderBaseId<TSession>(int OrderBaseId) where TSession : class, ISession
		{
			return await _orderDiscount.GetListByOrderBaseIdAsync<TSession>(OrderBaseId).ConfigureAwait(false);
		}

		//public async Task<List<Order_BaseEntity>> GetList<TSession>() where TSession : class, ISession
		//{
		//    return await _orderBase.GetList<ICasaMielSession>();
		//}
		/// <summary>
		/// Gets all store.
		/// </summary>
		/// <returns>The all store.</returns>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<List<StoreEntity>> GetAllStore<TSession>() where TSession : class, ISession
		{
			var list = await _mbrStoreRepository.GetAllAsync<TSession>().ConfigureAwait(false);
			return list.ToList();
		}

		/// <summary>
		/// Adds the notice async.
		/// </summary>
		/// <returns>The notice async.</returns>
		/// <param name="entity">Entity.</param>
		/// <param name="uow">Uow.</param>
		public async Task AddAsync(NoticeBaseEntity entity, IUnitOfWork uow)
		{
			await _noticeBase.SaveAsync(entity, uow).ConfigureAwait(true);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <returns>The mbr extend info async.</returns>
		/// <param name="entity">Entity.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task AddMbrExtendInfoAsync<TSession>(MbrExtendInfoEntity entity) where TSession : class, ISession
		{
			await _mbrExtendInfoRepository.SaveAsync<TSession>(entity).ConfigureAwait(false);
		}
		/// <summary>
		/// Updates the by relation identifier async.
		/// </summary>
		/// <returns>The by relation identifier async.</returns>
		/// <param name="RelationId">Relation identifier.</param>
		/// <param name="Status">Status.</param>
		/// <param name="uow">Uow.</param>
		public async Task UpdateNoticeByRelationIdAsync(int RelationId, int Status, IUnitOfWork uow)
		{
			await _noticeBase.UpdateByRelationIdAsync(RelationId, Status, uow).ConfigureAwait(true);
		}

		/// <summary>
		/// Gets the by store identifier async.
		/// </summary>
		/// <returns>The by store identifier async.</returns>
		/// <param name="StoreId">Store identifier.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<StoreEntity> GetByStoreIdAsync<TSession>(int StoreId) where TSession : class, ISession
		{
			return await _mbrStoreRepository.GetByStoreIdAsync<TSession>(StoreId).ConfigureAwait(false);
		}
		/// <summary>
		/// Gets the by relation identifier async.
		/// </summary>
		/// <returns>The by relation identifier async.</returns>
		/// <param name="RelationId">Relation identifier.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<StoreEntity> GetByRelationIdAsync<TSession>(int RelationId) where TSession : class, ISession
		{
			return await _mbrStoreRepository.GetByRelationIdAsync<TSession>(RelationId).ConfigureAwait(false);
		}
		/// <summary>
		/// Ges the rect range async.
		/// </summary>
		/// <returns>The rect range async.</returns>
		/// <param name="minLat">Minimum lat.</param>
		/// <param name="minLng">Minimum lng.</param>
		/// <param name="maxLat">Max lat.</param>
		/// <param name="maxLng">Max lng.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<List<StoreEntity>> GeRectRangeAsync<TSession>(double minLat, double minLng, double maxLat, double maxLng) where TSession : class, ISession
		{
			var list = await _mbrStoreRepository.GeRectRangeAsync<TSession>(minLat, minLng, maxLat, maxLng).ConfigureAwait(false);

			return list;
		}


		/// <summary>
		/// Gets the product tag async.
		/// </summary>
		/// <returns>The product tag async.</returns>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<List<Product_tagbaseEntity>> GetProductTagAsync<TSession>() where TSession : class, ISession
		{
			return await _productTagbaseRepository.GetListByStateAsync<TSession>(1, "OrderNo desc").ConfigureAwait(false);
		}



		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="TSession"></typeparam>
		/// <param name="StoreName"></param>
		/// <param name="pageIndex"></param>
		/// <param name="pageSize"></param>
		/// <returns></returns>
		public async Task<PagingResult<StoreEntity>> GetStoreByNameAsync<TSession>(string StoreName, int pageIndex, int pageSize) where TSession : class, ISession
		{
			var list = await _mbrStoreRepository.GetStoreByName<TSession>(StoreName, pageIndex, pageSize).ConfigureAwait(false);

			return list;
		}
		/// <summary>
		/// The mbr store entity.
		/// </summary>
		public async Task<List<StoreEntity>> GetStoreByNameAsync<TSession>(string StoreName) where TSession : class, ISession
		{
			var list = await _mbrStoreRepository.GetStoreByNameAsync<TSession>(StoreName).ConfigureAwait(false);

			return list;
		}

		/// <summary>
		/// Gets all store by name async.
		/// </summary>
		/// <returns>The all store by name async.</returns>
		/// <param name="StoreName">Store name.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<List<StoreEntity>> GetAllStoreByNameAsync<TSession>(string StoreName) where TSession : class, ISession
		{
			var list = await _mbrStoreRepository.GetAllStoreByNameAsync<TSession>(StoreName).ConfigureAwait(false);

			return list;
		}
		public async Task<List<StoreEntity>> GetListAsync<TSession>(string StoreName) where TSession : class, ISession
		{
			var list = await _mbrStoreRepository.GetListAsync<TSession>(StoreName, 1).ConfigureAwait(false);
			return list;
		}


		/// <summary>
		/// Gets the by order code async.
		/// </summary>
		/// <returns>The by order code async.</returns>
		/// <param name="orderCode">Order code.</param>
		/// <param name="mobile">mobile</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<OrderBaseEntity> GetByOrderCodeAsync<TSession>(string orderCode, string mobile) where TSession : class, ISession
		{
			return await _orderBase.GetByOrderCodeAsync<TSession>(orderCode, mobile).ConfigureAwait(false);
		}

		public async Task<OrderBaseEntity> GetByOrderCodeAsync<TSession>(string orderCode) where TSession : class, ISession
		{
			return await _orderBase.GetByOrderCodeAsync<TSession>(orderCode).ConfigureAwait(false);
		}
		public async Task<List<Order_GoodsEntity>> GetGoodsByOrderBaseIdAsync<TSession>(int orderBaseId) where TSession : class, ISession
		{
			return await _orderGoods.GetByOrderBaseIdAsync<TSession>(orderBaseId).ConfigureAwait(false);
		}
		/// <summary>
		/// UPs the date.
		/// 订单状态，1：新建、2：已支付、7：已完成 、8：已取消 、9：交易关闭
		/// </summary>
		/// <returns>The date.</returns>
		/// <param name="entity">Entity.</param>
		/// <param name="uow">Uow.</param>
		public async Task<bool> OrderBaseUPdateAsync(OrderBaseEntity entity, IUnitOfWork uow)
		{
			return await _orderBase.UpdateAsync(entity, uow).ConfigureAwait(true);
		}

		/// <summary>
		/// Deletes the async.
		/// </summary>
		/// <returns>The async.</returns>
		/// <param name="OrderCode">Order code.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task DeleteAsync<TSession>(string OrderCode) where TSession : class, ISession
		{
			await _orderBase.DeleteAsync<TSession>(OrderCode).ConfigureAwait(false);
		}
		/// <summary>
		/// Updates the order status and res bill NOA sync.
		/// </summary>
		/// <returns>The order status and res bill NOA sync.</returns>
		/// <param name="entity">OldEntity.</param>
		/// <param name="NewOrderStatus">New order status.</param>
		/// <param name="Resbillno">Resbillno.</param>
		/// <param name="uow">Uow.</param>
		public async Task<bool> UpdateOrderStatusAndResBillNOAsync(OrderBaseEntity entity, int NewOrderStatus, string Resbillno, IUnitOfWork uow)
		{
			return await _orderBase.UpdateOrderStatusAndResBillNOAsync(entity, NewOrderStatus, Resbillno, uow).ConfigureAwait(true);
		}
		/// <summary>
		/// Updates the order tacke status.
		/// </summary>
		/// <returns>The order tacke status.</returns>
		/// <param name="OrderBaseId">Order base identifier.</param>
		/// <param name="Status">Status.</param>
		/// <param name="billno">billno</param>
		/// <param name="uow">Uow.</param>
		public async Task<bool> UpdateOrderTakeStatus(int OrderBaseId, int Status, string billno, IUnitOfWork uow)
		{
			return await _orderTake.UpdateStatus(OrderBaseId, Status, billno, uow).ConfigureAwait(true);
		}
		/// <summary>
		/// Gets the orde take by order code async.
		/// </summary>
		/// <returns>The orde take by order code async.</returns>
		/// <param name="orderCode">Order code.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<Order_TakeEntity> GetOrdeTakeByOrderCodeAsync<TSession>(int OrderBaseId) where TSession : class, ISession
		{
			return await _orderTake.GetByOrderBaseIdAsync<TSession>(OrderBaseId).ConfigureAwait(false);
		}
		/// <summary>
		/// Updates the order discount status.
		/// 优惠券状态：0正常，1取消
		/// </summary>
		/// <returns>The order discount status.</returns>
		/// <param name="OrderBaseId">Order base identifier.</param>
		/// <param name="Status">Status.</param>
		/// <param name="uow">Uow.</param>
		public async Task<bool> UpdateOrderDiscountStatus(int OrderBaseId, int Status, IUnitOfWork uow)
		{
			return await _orderDiscount.UpdateStatus(OrderBaseId, Status, uow).ConfigureAwait(true);
		}
		/// <summary>
		/// Gets the un pay order list async.
		/// </summary>
		/// <returns>The un pay order list async.</returns>
		/// <param name="n">N.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<List<OrderBaseEntity>> GetUnPayOrderListAsync<TSession>(int n) where TSession : class, ISession
		{
			return await _orderBase.GetListAsync<TSession>(n).ConfigureAwait(false);
		}
		/// <summary>
		/// Gets the list async.
		/// </summary>
		/// <returns>The list async.</returns>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<List<GoodBaseEntity>> GetGoodBaseListAsync<TSession>() where TSession : class, ISession
		{
			return await _goodBaseRepository.GetListAsync<TSession>().ConfigureAwait(false);
		}
		/// <summary>
		/// Gets the payed order list async.
		/// </summary>
		/// <returns>The payed order list async.</returns>
		/// <param name="source">Source.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<List<OrderBaseEntity>> GetPayedOrderListAsync<TSession>(int source) where TSession : class, ISession
		{
			return await _orderBase.GetPayedOrderListAsync<TSession>(source).ConfigureAwait(false);
		}
		/// <summary>
		/// Updates the order status and res bill NOA sync.
		/// </summary>
		/// <returns>The order status and res bill NOA sync.</returns>
		/// <param name="OrderBaseId">Order base identifier.</param>
		/// <param name="OrderStatus">Order status.</param>
		/// <param name="Resbillno">Resbillno.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task UpdateOrderStatusAndResBillNOAsync<TSession>(int OrderBaseId, int OrderStatus, string Resbillno) where TSession : class, ISession
		{
			await _orderBase.UpdateOrderStatusAndResBillNOAsync<TSession>(OrderBaseId, OrderStatus, Resbillno).ConfigureAwait(false);
		}



		/// <summary>
		/// Gets the by ELES tore identifier async.
		/// </summary>
		/// <returns>The by ELES tore identifier async.</returns>
		/// <param name="ELEStoreId">ELES tore identifier.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<StoreEntity> GetByELEStoreIdAsync<TSession>(string ELEStoreId) where TSession : class, ISession
		{
			return await _mbrStoreRepository.GetByELEStoreIdAsync<TSession>(ELEStoreId).ConfigureAwait(false);
		}

		/// <summary>
		/// Get the specified StoreId.
		/// </summary>
		/// <returns>The get.</returns>
		/// <param name="StoreId">Store identifier.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<StoreEntity> GetDetail<TSession>(int StoreId) where TSession : class, ISession
		{
			var entity = await _mbrStoreRepository.GetKeyAsync<TSession>(StoreId).ConfigureAwait(false);
			//if (_casamielSettings.ApiName == "hgspApi")
			//{
			//    if (entity != null)
			//    {
			//        if (entity.DefaultExpress > 0)
			//            entity.IsOpenSend = 1;
			//        else
			//        {
			//            entity.IsOpenSend = 0;
			//        }
			//    }
			//}
			return entity;
		}
		/// <summary>
		/// Gets the detail by releation identifier async.
		/// </summary>
		/// <returns>The detail by releation identifier async.</returns>
		/// <param name="RelationId">Relation identifier.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<GoodBaseEntity> GetGoodDetailByReleationIdAsync<TSession>(int RelationId) where TSession : class, ISession
		{
			return await _goodBaseRepository.GetDetailByReleationIdAsync<TSession>(RelationId).ConfigureAwait(false);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="TSession"></typeparam>
		/// <param name="RelationId"></param>
		/// <returns></returns>
		public async Task<GoodBaseEntity> GetDetailV2ByReleationIdAsync<TSession>(int RelationId) where TSession : class, ISession
		{
			return await _goodBaseRepository.GetDetailV2ByReleationIdAsync<TSession>(RelationId).ConfigureAwait(false);
		}
		/// <summary>
		/// Goodses the quantity by pid async.
		/// </summary>
		/// <returns>The quantity by pid async.</returns>
		/// <param name="pid">Pid.</param>
		/// <param name="dt">Dt.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<int> GetGoodsQuantityByPidAsync<TSession>(int pid, DateTime dt) where TSession : class, ISession
		{
			return await _orderBase.GetGoodsQuantityByPidAsync<TSession>(pid, dt).ConfigureAwait(false);
		}
		/// <summary>
		/// Updates the stock.
		/// </summary>
		/// <returns>The stock.</returns>
		/// <param name="storeid">Storeid.</param>
		/// <param name="pid">Pid.</param>
		/// <param name="stock">Stock.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task UpdateStockAsync<TSession>(int storeid, int pid, int stock) where TSession : class, ISession
		{
			await _goodBaseRepository.UpdateStock<TSession>(storeid, pid, stock).ConfigureAwait(false);
		}
		/// <summary>
		/// Updates the stock v2 async.
		/// </summary>
		/// <returns>The stock v2 async.</returns>
		/// <param name="storeid">Storeid.</param>
		/// <param name="pid">Pid.</param>
		/// <param name="stock">Stock.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task UpdateStockV2Async<TSession>(int storeid, int pid, int stock) where TSession : class, ISession
		{
			await _goodBaseRepository.UpdateStockV2<TSession>(storeid, pid, stock).ConfigureAwait(false);
		}
		/// <summary>
		/// Gets the product identifier s async.
		/// </summary>
		/// <returns>The product identifier s async.</returns>
		/// <param name="StoreId">Store identifier.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task<List<string>> GetProductIDsAsync<TSession>(int StoreId) where TSession : class, ISession
		{
			return await _goodBaseRepository.GetProductIDsAsync<TSession>(StoreId).ConfigureAwait(false);
		}

		/// <summary>
		/// Updates the order invoice URL by order code async.
		/// </summary>
		/// <returns>The order invoice URL by order code async.</returns>
		/// <param name="OrderCode">Order code.</param>
		/// <param name="InvoiceQrcode">Invoice URL.</param>
		/// <typeparam name="TSession">The 1st type parameter.</typeparam>
		public async Task UpdateOrderInvoiceUrlByOrderCodeAsync<TSession>(string OrderCode, string InvoiceQrcode) where TSession : class, ISession
		{
			await _orderBase.UpdateOrderInvoiceUrlByOrderCodeAsync<TSession>(OrderCode, InvoiceQrcode).ConfigureAwait(false);
		}
	}
}
